#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""MySQLPass简化打包脚本
用于将mysqlpass项目快速打包成一个可独立运行的exe程序
跳过自动安装依赖步骤，假设用户已经安装了所有必要的依赖
"""

import os
import sys
import subprocess
import shutil
from datetime import datetime

# 确保脚本在正确的目录下运行
script_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_dir)

# 定义项目相关路径和参数
BUILD_NAME = "MySQLPass"
BUILD_VERSION = "1.0.0"
MAIN_SCRIPT = "main.py"


def check_pyinstaller():
    """检查PyInstaller是否已安装"""
    try:
        subprocess.run([sys.executable, "-m", "PyInstaller", "--version"], 
                      check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return True
    except (subprocess.CalledProcessError, FileNotFoundError):
        return False


def install_pyinstaller():
    """安装PyInstaller"""
    print("正在安装PyInstaller...")
    try:
        subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], 
                      check=True)
        print("PyInstaller安装成功")
        return True
    except subprocess.CalledProcessError:
        print("PyInstaller安装失败，请手动安装: python -m pip install pyinstaller")
        return False


def clean_build_dir():
    """清理之前的构建文件"""
    print("清理之前的构建文件...")
    
    # 清理PyInstaller生成的目录
    for dir_name in ["build", "dist"]:
        dir_path = os.path.join(script_dir, dir_name)
        if os.path.exists(dir_path):
            try:
                shutil.rmtree(dir_path)
                print(f"已清理目录: {dir_name}")
            except Exception as e:
                print(f"清理目录失败 {dir_name}: {e}")
    
    # 清理spec文件
    for file in os.listdir(script_dir):
        if file.endswith(".spec"):
            try:
                os.remove(os.path.join(script_dir, file))
                print(f"已清理spec文件: {file}")
            except Exception as e:
                print(f"清理spec文件失败 {file}: {e}")


def create_version_info_file():
    """创建版本信息文件"""
    # 预先处理版本号
    major, minor, patch = BUILD_VERSION.split('.')
    current_year = datetime.now().year
    
    # 使用普通字符串和字符串格式化，避免f-string中的空格问题
    version_info_content = """
VSVersionInfo({{
  'ffi': {{'ffiwValue': 16777216}},
  'mask': 0x3f,
  'os': 0x40004,
  'filevers': ({0}, {1}, {2}, 0),
  'prodvers': ({0}, {1}, {2}, 0),
  'pszOSVerName': 'Windows NT',
  'pszFileDesc': 'MySQLPass - 自由使用的MySQL工具',
  'pszInternalName': 'MySQLPass',
  'pszOriginalFilename': 'MySQLPass.exe',
  'pszProductName': 'MySQLPass',
  'pszCompanyName': 'MySQLPass Team',
  'pszLegalCopyright': '© {3} MySQLPass. All rights reserved.',
  'pszLegalTrademarks': '',
  'pszComments': '安全、便捷的MySQL密码管理解决方案'
}}
)
"""
    
    # 应用format方法填充占位符
    version_info_content = version_info_content.format(major, minor, patch, current_year)
    
    version_info_path = "version_info.txt"
    with open(version_info_path, "w", encoding="utf-8") as f:
        f.write(version_info_content)
    
    return version_info_path


def build_with_pyinstaller():
    """使用PyInstaller打包应用"""
    print(f"开始打包MySQLPass项目为独立可执行程序...")
    
    # 创建版本信息文件
    version_info_path = create_version_info_file()
    
    # 构建PyInstaller命令参数
    cmd = [
        sys.executable,
        "-m",
        "PyInstaller",
        "--name", BUILD_NAME,
        "--windowed",  # 不显示控制台窗口
        "--icon", os.path.join("src", "data", "mp.png"),  # 使用图标
        "--version-file", version_info_path,
        "--collect-all", "pymysql",
        "--collect-all", "cryptography",
        "--collect-all", "click",
        "--collect-all", "prettytable",
        "--collect-all", "pandas",
        "--collect-all", "openpyxl",
        "--collect-all", "xlwt",
        "--collect-all", "requests",
        "--add-data", f"src{os.pathsep}src",
        "--add-data", f"README.md{os.pathsep}.",
        "--add-data", f"README.en.md{os.pathsep}.",
        "--noupx",  # 禁用UPX压缩
        "--onefile",  # 打包成单个可执行文件
        MAIN_SCRIPT
    ]
    
    # 执行打包命令
    try:
        print(f"执行打包命令...")
        subprocess.run(cmd, check=True)
        print("打包成功")
        return True
    except subprocess.CalledProcessError as e:
        print(f"打包失败: {e}")
        return False
    except Exception as e:
        print(f"打包过程中发生未知错误: {e}")
        return False


def verify_build():
    """验证打包结果"""
    exe_path = os.path.join("dist", f"{BUILD_NAME}.exe")
    if os.path.exists(exe_path):
        print(f"\n=== 打包完成 ===")
        print(f"独立可执行文件已生成: {exe_path}")
        print(f"文件大小: {os.path.getsize(exe_path) / 1024 / 1024:.2f} MB")
        print("\n可以直接运行该exe文件，无需安装Python环境")
        return True
    else:
        print(f"打包失败: 未找到生成的可执行文件 {exe_path}")
        return False


def main():
    """主函数"""
    print("=====================================")
    print(f"MySQLPass v{BUILD_VERSION} 简化打包工具")
    print("=====================================")
    
    # 检查PyInstaller是否已安装
    if not check_pyinstaller():
        if not install_pyinstaller():
            print("PyInstaller安装失败，无法继续打包")
            sys.exit(1)
    
    # 清理之前的构建文件
    clean_build_dir()
    
    # 开始打包
    if build_with_pyinstaller():
        # 验证打包结果
        verify_build()
    else:
        print("打包失败，请检查错误信息")
        sys.exit(1)


if __name__ == "__main__":
    main()